local Element=class()
function Element:ctor(symbol,style)
	self.className="Element"
	self.style=style or {}
	if App.isClass(self,Stage) then
		self.ccNode=_G["CCScene"]["create"](_G["CCScene"])
	else
		self.ccNode=_G["CCLayer"]["create"](_G["CCLayer"])
		self.ccLayer=self.ccNode
		self.ccLayer["setAnchorPoint"](self.ccLayer,CCPoint(0,0))
	end
	self.ccNode.bindObj=self
	
	if self.style.symbol then symbol=self.style.symbol end
	self.symbol=symbol
	self.id=0
	self.x=0
	self.y=0
	self.z=0
	self.z2=0
	self.width=0
	self.height=0
	self.visible=true
	self.alpha=1
	self.scaleX=1
	self.scaleY=1
	self.rotation=0
	self.numChildren=0
	self.children=Array.new()
	local baseStyle=App.styles[symbol]
	if baseStyle~=nil then
		for k in pairs(baseStyle) do
			if self.style[k]==nil then
				self.style[k]=baseStyle[k]
			end
		end
	end
	if self.style.id then
		self.id=App.toInt(self.style.id)
		self.style.id=nil
	end
	if self.style.name then
		self.name=self.style.name
		self.style.name=nil
	end
	local x=0
	local y=0
	if self.style.x then
		x=self.style.x
		self.style.x=nil
	end
	if self.style.y then
		y=self.style.y
		self.style.y=nil
	end
	self:setPosition(x,y)
	if self.style.scaleX then
		self:setScaleX(self.style.scaleX)
		self.style.scaleX=nil
	end
	if self.style.scaleY then
		self:setScaleY(self.style.scaleY)
		self.style.scaleY=nil
	end
	if self.style.visible then
		self:setVisible(self.style.visible)
		self.style.visible=nil
	end
	if self.style.hitBounds then
		self.hitBounds=App.formatArray(self.style.hitBounds)
	end
	if self.style.param and String.indexOf(self.style.param,"{")>-1 and String.indexOf(self.style.param,"}")>-1 then
		self.paramExpr=self.style.param
		self.style.param=nil
	end
	local enabled=App.isClass(self,Button) and true or false
	if self.hitBounds then enabled=true end
	if self.style.enabled~=nil then enabled=self.style.enabled end
	if self.ccLayer then self:setEnabled(enabled) end
end
function Element:contains(target)
	while target do
		if self==target then return true end
		target=target.parent
	end
	return false
end

function Element:remove()
	if self.parent==nil then return end
	self.parent.ccNode["removeChild"](self.parent.ccNode,self.ccNode,true)
	local index=self.parent.children:indexOf(self)
	self.parent.children:splice(index,1)
	self.parent.numChildren=self.parent.children.length
	self.parent=nil
end

function Element:removeChildren()
	self.ccNode["removeAllChildrenWithCleanup"](self.ccNode,true)
	for i=0,self.children.length-1 do
		local child=self.children[i]
		child.parent=nil
	end
	self.children:splice(0)
	self.numChildren=0
end
function Element:addChild(child)
	return self:addChildAt(child,-1)
end
function Element:addChildAt(child,index)
	if index==-1 then index=self.children.length end
	local resetLast=false
	if child.parent==self then
		local index2=self.children:indexOf(child)
		if index2==index then return child end
		if index>index2 then index=index-1 end
		self.children:splice(index2,1)
		self.children:splice(index,0,child)
	else
		if child.parent then
			child.ccNode["retain"](child.ccNode)
			child:remove()
			self.ccNode["addChild"](self.ccNode,child.ccNode)
			child.ccNode["release"](child.ccNode)
		else
			self.ccNode["addChild"](self.ccNode,child.ccNode)
		end
		child.parent=self
		self.children:splice(index,0,child)
		if index==self.children.length-1 then resetLast=true end
	end
	for i=self.children.length-1,0,-1 do
		local child2=self.children[i]
		self.ccNode["reorderChild"](self.ccNode,child2.ccNode,i)
		if resetLast then break end
	end
	self.numChildren=self.children.length
	return child
end

function Element:getChildAt(index)
	return self.children[index]
end
function Element:getChildByName(name)
	for i=0,self.children.length-1 do
		local child=self.children[i]
		if child.name==name then return child end
	end
	return nil
end
function Element:getBox(name)
	return self:getChildByName(name)
end
function Element:getChildById(id)
	for i=0,self.children.length-1 do
		local child=self.children[i]
		if child.id==id then return child end
	end
	return nil
end
function Element:setPosition(x,y)
	if (x==self.x) and (y==self.y) then return end
	self.ccNode["setPosition"](self.ccNode,App.toInt(x),-App.toInt(y))
	self.x=tonumber(x)
	self.y=tonumber(y)
end
function Element:setSize(w,h)
	self.width=w
	self.height=h
end
function Element:localToGlobal(x,y)
	if x==nil then x=0 end
	if y==nil then y=0 end
	local p=self.ccNode["convertToWorldSpace"](self.ccNode,CCPoint(x,-y))
	return Array.new(p.x,-p.y-App.stage.y)
end
function Element:globalToLocal(x,y)
	if x==nil then x=0 end
	if y==nil then y=0 end
	local p=self.ccNode["convertToNodeSpace"](self.ccNode,CCPoint(x,-y))
	return Array.new(p.x,App.stage.y-p.y)
end
function Element:hitTest(x,y)
	local bounds=self.hitBounds
	if self.width==0 and bounds==nil then return true end
	local p=self:localToGlobal()
	if App.isClass(self,Clip) and self.centerPos then
		p[0]=p[0]-self.centerPos[0]
		p[1]=p[1]-self.centerPos[1]
	end
	x=x-p[0]
	y=y-p[1]
	if bounds==nil then
		return x>0 and y>0 and x<self.width*self.scaleX and y<self.height*self.scaleY
	end
	local polygonArea=0
	local trigonArea=0
	for i=0,bounds.length-1 do
		local b=bounds[i]
		local b2=bounds[i==0 and bounds.length-1 or i-1]
		polygonArea = polygonArea+b[0] * b2[1] - b2[0] * b[1]
		trigonArea = trigonArea+Math.abs(x * b[1] -x*b2[1]-b[0]*y+b[0]*b2[1]+b2[0]*y-b2[0]*b[1])
	end
	return Math.abs(Math.abs(polygonArea)-trigonArea)<=1
end
function Element:dispatchEvent(evt)
	evt.target=self
	local currTarget=self
	while currTarget do
		local method=nil
		if currTarget.eventListener then
			for name in pairs(currTarget.eventListener) do
				local hash=currTarget.eventListener[name]
				if hash.event==evt.type then
					if hash.dispatcher==nil or hash.dispatcher=="" or hash.dispatcher==self.name then
						method=currTarget[name]
					end
				end
			end
		end
		if method then method(currTarget,evt) end
		if evt.parentOfRemoved then
			currTarget=evt.parentOfRemoved
			evt.parentOfRemoved=nil
		else
		
			currTarget=currTarget.parent
		end
	end
end
function Element:onTouchEvent(evtType,x,y)
	if not App.stage.enabled then return end
	if evtType=="began" then
		self:dispatchEvent({type="press",x=x,y=y})
	elseif evtType=="moved" then
		self:dispatchEvent({type="move",x=x,y=y})
	elseif evtType=="ended" then
		self:dispatchEvent({type="release",x=x,y=y})
		if self:hitTest(x,y) then
			self:dispatchEvent({type="click",x=x,y=y})
		end
	end
end
function Element:getStage()
	local parent=self.parent
	while parent do
		if parent==App.stage then return App.stage end
		parent=parent.parent
	end
	return nil
end
function Element:setZ(z,z2)
	self.z=z
	self.z2=z2 or 0
end
function Element:setX(v)
	self:setPosition(v,self.y)
end
function Element:setY(v)
	self:setPosition(self.x,v)
end
function Element:setWidth(v)
	self:setSize(v,self.height)
end
function Element:setHeight(v)
	self:setSize(self.width,v)
end
function Element:setScaleX(v)
	self.scaleX=v
	self.ccNode["setScaleX"](self.ccNode,v)
end
function Element:setScaleY(v)
	self.scaleY=v
	self.ccNode["setScaleY"](self.ccNode,v)
end
function Element:setScale(scaleX,scaleY)
	if scaleY==nil then scaleY=scaleX end
	self:setScaleX(scaleX)
	self:setScaleY(scaleY)
end
function Element:setVisible(v)
	self.visible=v
	self.ccNode["setVisible"](self.ccNode,v)
end
function Element:setRotation(v)
	self.rotation=v
	self.ccNode["setRotation"](self.ccNode,v)
end
function Element:setAlpha(v)
	self.alpha=Math.min(Math.max(v,0),1)
	local queues={self.ccNode}
	while #queues>0 do
		local ccNode=queues[#queues]
		table.remove(queues,#queues)
		local ccArr=ccNode["getChildren"](ccNode)
		local count=ccArr and ccArr["count"](ccArr) or 0
		for i=0,count-1 do
			local ccObj=ccArr["objectAtIndex"](ccArr,i)
			local ccNode2=_G["tolua"]["cast"](ccObj,"CCNode")
			if ccNode2.bindObj then
				_G["table"]["insert"](queues,1,ccNode2)
			elseif ccNode2.isBitmap then
				ccNode2["setOpacity"](ccNode2,self.alpha*255)
			end
		end
		
	end
end
function Element:setEnabled(v)
	if self.enabled==v then return end
	self.enabled=v
	
	if not self.ccLayer then return end
	self.ccLayer["unregisterScriptTouchHandler"](self.ccLayer)
	self.ccLayer["setTouchEnabled"](self.ccLayer,false)
	if not self.enabled then return end
	
	local function onTouchIn(evtType,x,y)
		local parent=self
		while parent do
			if not parent.visible then return end
			parent=parent.parent
		end
		x=App.toInt(x)
		y=-App.toInt(y)-App.stage.y
		if evtType=="began" then
			if self:hitTest(x,y)==false then return false end
			App.pressElementX=self.x
			App.pressElementY=self.y
			App.pressX=x
			App.pressY=y
			App.isPress=true
		elseif evtType=="moved" then
			App.moveX=x
			App.moveY=y
		end
		if evtType=="ended" then
			App.isPress=false
		end
		self.onTouchEvent(self,evtType,x,y)
		return true
	end
	App.touchIndex=App.touchIndex-1
	self.ccLayer["registerScriptTouchHandler"](self.ccLayer,onTouchIn,false,App.touchIndex,true)
	self.ccLayer["setTouchEnabled"](self.ccLayer,true)
end
function Element:setHitBounds(v)
	self.hitBounds=v
end
function Element:setParam(v)
	
end
function Element:toString()
	return "["..self.className..(self.name and " "..self.name or "").."]"
end
return Element